import BackGround from './base/background'
import Support from "./base/support"

wx.setPreferredFramesPerSecond(12)
wx.showShareMenu()

let ctx = canvas.getContext('2d')
var w = canvas.width
var h = canvas.height
var csl = 0.18 * w
var fsz = 0.07 * w

var fontstyle = fsz + "px 楷体"


let sp = new Support(w, h)

var board = new Array();
var score = 0;
var topScore = 0;
var hasConflicted = new Array();
var direction = {
  left: 1,
  up: 2,
  down: 3,
  right: 4
};


let startX //触摸时的坐标   
let startY
let x //滑动的距离   
let y

/**
 * 游戏主函数
 */
export default class Main {
  constructor() {
    // 维护当前requestAnimationFrame的id
    this.aniId = 0

    this.restart()
    // 激活重启按钮事件
    wx.onTouchStart(this.touchEventHandler.bind(this))

    // 开启滑动事件监听
    wx.onTouchStart(this.touchStart)
    wx.onTouchMove(this.touchMove)
    wx.onTouchEnd(this.touchEnd.bind(this))
  }

  restart() {
    // console.log(w, h)
    this.bg = new BackGround(ctx, w, h)

    // 获取本地存储的最高分数(若有)
    wx.getStorage({
      key: "topScore",
      success(res) {
        // console.log(res.data)
        topScore = res.data
      }
    })
    // 重置当前分数
    score = 0;
    // 显示新分数
    this.updateScore(score)

    // 初始化棋盘格
    this.init();
    // 在随机两个格子生成数字
    this.generateOneNumber();
    this.generateOneNumber();
    // 更新游戏面板
    this.render();
  }

  init() {
    for (var i = 0; i < 4; i++) {
      for (var j = 0; j < 4; j++) {
        ctx.fillStyle = '#CCC0B3'
        ctx.fillRect(sp.getPostionLeft(i, j), sp.getPostionTop(i, j), csl, csl)
      }
    }

    //初始化棋盘
    for (var i = 0; i < 4; i++) {
      board[i] = new Array();
      hasConflicted[i] = new Array();
      for (var j = 0; j < 4; j++) {
        board[i][j] = 0;
        hasConflicted[i][j] = false;
      }
    }
    // console.log(board);
    //更新面板
    this.render();
  }

  // 棋盘重绘
  render() {
    // 清空棋盘, 重新刷新
    ctx.clearRect(20.04 * w, 50 + 0.3 * w, 0.92 * w, 0.92 * w);
    ctx.fillStyle = '#BBADA0'
    ctx.fillRect(0.04 * w, 50 + 0.3 * w, 0.92 * w, 0.92 * w)
    for (var i = 0; i < 4; i++) {
      for (var j = 0; j < 4; j++) {
        if (board[i][j] == 0) {
          // 绘制无字空图
          ctx.fillStyle = '#CCC0B3'
          ctx.fillRect(sp.getPostionLeft(i, j), sp.getPostionTop(i, j), csl, csl)
        } else {
          // 根据数字颜色设置器背景色
          ctx.fillStyle = sp.getBackgroundColorByNum(board[i][j])
          ctx.fillRect(sp.getPostionLeft(i, j), sp.getPostionTop(i, j), csl, csl)
          // 设置文字颜色, 大小, 字体, 对其方式
          ctx.fillStyle = sp.getPreColorByNum(board[i][j])
          // 显示数字(文字)
          ctx.font = fontstyle
          ctx.textAlign = "left"
          ctx.textBaseline = "top"
          // 获取文字
          var st = sp.getShowTextByNum(board[i][j])
          // 将4字分两行绘制(有5字的份为前3后2)

          var st2 = st.slice(-2)
          var st1 = st.slice(0, st.length - 2)

          ctx.fillText(st1, sp.getPostionLeft(i, j) + 0.02 * w, sp.getPostionTop(i, j) + 0.01 * w);
          ctx.fillText(st2, sp.getPostionLeft(i, j) + 0.02 * w, sp.getPostionTop(i, j) + fsz + 0.02 * w);

          hasConflicted[i][j] = false;
        }
      }
    }
  }

  generateOneNumber() {
    if (sp.isNoSpace(board)) {
      return false;
    }
    //随机一个位置
    var randx = parseInt(Math.floor(Math.random() * 4));
    var randy = parseInt(Math.floor(Math.random() * 4));
    //判断生成的坐标是否合理(无值,位置即可使用)
    while (true) {
      if (board[randx][randy] === 0)
        break;
      //若果该坐标存在了值,即不合理,继续生成随机一个位置
      randx = parseInt(Math.floor(Math.random() * 4));
      randy = parseInt(Math.floor(Math.random() * 4));
    }

    //随机一个数字
    var randNum = Math.random() < 0.6 ? 2 : 4;
    board[randx][randy] = randNum;
    // showNumberWithAnimation(randx, randy, randNum);
    this.render()
    return true;
  }

  /**
   * 滑动处理 1, 左滑; 2, 上滑, 3, 右滑; 4, 下滑
   */
  slideDirection(numm) {
    switch (numm) {
      case 1: //left
        if (this.moveLeft()) {
          setTimeout(this.generateOneNumber.bind(this), 210);
          setTimeout(this.isGameOver.bind(this), 300);
        }
        break;
      case 2: //up
        if (this.moveUp()) {
          setTimeout(this.generateOneNumber.bind(this), 210);
          setTimeout(this.isGameOver.bind(this), 300);
        }
        break;
      case 3: //right
        if (this.moveRight()) {
          setTimeout(this.generateOneNumber.bind(this), 210);
          setTimeout(this.isGameOver.bind(this), 300);
        }
        break;
      case 4: //down
        if (this.moveDown()) {
          setTimeout(this.generateOneNumber.bind(this), 210);
          setTimeout(this.isGameOver.bind(this), 300);
        }
        break;
      default:
        break;
    }
  }

  moveLeft() {
    if (!sp.canMove(board, direction.left))
      return false;
    //左移
    for (var i = 0; i < 4; i++) {
      for (var j = 1; j < 4; j++) {
        if (board[i][j] !== 0) {
          for (var k = 0; k < j; k++)
            //可以一次移动多个格子
            if (board[i][k] == 0 && sp.noBlockHorizontal(i, k, j, board)) {
              //move
              // showMoveAnimation(i, j, i, k);
              board[i][k] = board[i][j];
              board[i][j] = 0;
              continue;
            } else if (board[i][k] == board[i][j] && sp.noBlockHorizontal(i, k, j, board) && !hasConflicted[i][k]) {
            //move
            // showMoveAnimation(i, j, i, k);
            //add
            board[i][k] += board[i][j];
            board[i][j] = 0;
            // var element = $("#grid-cell-" + i + k);
            // anp(element, board[i][k])
            score += board[i][k];
            this.updateScore(score)
            continue;
          }
        }
      }
    }
    setTimeout(this.render, 200); //等待200在执行更新面板操作,避免动画效果被冲掉
    return true
  }

  moveRight() {
    if (!sp.canMove(board, direction.right))
      return false;
    //右移
    for (var i = 3; i >= 0; i--) {
      for (var j = 2; j >= 0; j--) {
        //该位置不等于0即可进行移动
        if (board[i][j] != 0)
          for (var k = 3; k > j; k--) {
            //如果可以一次移动多个格子
            if (board[i][k] == 0 && sp.noBlockHorizontal(i, j, k, board)) {
              //move
              // showMoveAnimation(i, j, i, k);
              board[i][k] = board[i][j];
              board[i][j] = 0;
              continue;
            } else if (board[i][k] == board[i][j] && sp.noBlockHorizontal(i, j, k, board) && !hasConflicted[i][k]) {
              //move
              // showMoveAnimation(i, j, i, k);
              //add
              board[i][k] += board[i][j];
              board[i][j] = 0;
              score += board[i][k];
              // var element = $("#grid-cell-" + i + k);
              // anp(element, board[i][k])
              this.updateScore(score)
              continue;
            }
          }
      }
    }
    setTimeout(this.render, 200); //等待200在执行更新面板操作,避免动画效果被冲掉
    return true
  }

  /**
    先判断第一列*/
  moveUp() {
    if (!sp.canMove(board, direction.up))
      return false;
    for (var i = 0; i < 4; i++) {
      for (var j = 1; j < 4; j++) {
        //该位置不为0即可进行移动
        if (board[j][i] != 0) {
          for (var k = 0; k < j; k++) {
            if (board[k][i] == 0 && sp.noBlockVectal(i, k, j, board)) {
              //move
              // showMoveAnimation(j, i, k, i);
              board[k][i] = board[j][i];
              board[j][i] = 0;
              continue;
            } else if (board[k][i] == board[j][i] && sp.noBlockVectal(i, k, j, board) && !hasConflicted[k][i]) {
              //move
              // showMoveAnimation(j, i, k, i);
              board[k][i] += board[j][i];
              board[j][i] = 0;
              score += board[k][i];
              // var element = $("#grid-cell-" + k + i);
              // anp(element, board[k][i])
              this.updateScore(score);
              continue;
            }
          }
        }
      }
    }
    setTimeout(this.render, 200); //等待200在执行更新面板操作,避免动画效果被冲掉
    return true
  }

  /**
    先判断第一列*/
  moveDown() {
    if (!sp.canMove(board, direction.down))
      return false;
    for (var i = 3; i >= 0; i--) {
      for (var j = 2; j >= 0; j--) {
        //该位置不为0即可进行移动
        if (board[j][i] != 0) {
          for (var k = 3; k > j; k--) {
            if (board[k][i] == 0 && sp.noBlockVectal(i, j, k, board)) {
              //move
              // showMoveAnimation(j, i, k, i);
              board[k][i] = board[j][i];
              board[j][i] = 0;
              continue;
            } else if (board[k][i] == board[j][i] && sp.noBlockVectal(i, j, k, board) && !hasConflicted[k][i]) {
              //move
              // showMoveAnimation(j, i, k, i);
              board[k][i] += board[j][i];
              board[j][i] = 0;
              score += board[k][i];
              // var element = $("#grid-cell-" + k + i);
              // anp(element, board[k][i])
              this.updateScore(score);
              continue;
            }
          }
        }
      }
    }
    // this.render()
    setTimeout(this.render, 200) //等待200在执行更新面板操作,避免动画效果被冲掉
    return true
  }

  isGameOver() {
    if (sp.isNoSpace(board) && !sp.canMoveAll(board)) {
      this.gameOver()
    }
  }

  gameOver() {
    // 本地存储最高分数
    wx.setStorage({
      key: "topScore",
      data: topScore
    })
    // 棋盘中出现 游戏结束!C2B6AB
    ctx.fillStyle = '#F7921E'
    ctx.fillRect(0.2 * w, 50 + 0.56 * w, 0.6 * w, 0.4 * w)
    ctx.fillStyle = 'white'
    ctx.font = "40px 微软雅黑"
    ctx.textAlign = "center"
    ctx.textBaseline = "middle"
    ctx.fillText("游戏结束!", 0.5 * w, 50 + 0.76 * w);
    console.log("游戏结束!")
    // alert("游戏结束!")
  }

  /**
   * 滑动处理 touchStart 记录起点; touchMove 记录x,y方向分别移动的距离; touchEnd 判断移动方向
   */
  touchStart(e) {
    var touch = e.touches[0]
    startX = touch.pageX //刚触摸时的坐标
    startY = touch.pageY //刚触摸时的坐标
  }

  touchMove(e) { //滑动
    var touch = e.touches[0]
    x = touch.pageX - startX //滑动的距离
    y = touch.pageY - startY //滑动的距离      
  }

  touchEnd(e) { //手指离开屏幕
    // console.log(x)
    // console.log(y)
    var xy = Math.abs(x) - Math.abs(y)
    var d = 0
    if (xy > 0) {
      if (x >= 0) {
        d = 3
      } else {
        d = 1
      }
    } else {
      if (y >= 0) {
        d = 4
      } else {
        d = 2
      }
    }

    this.slideDirection(d)
  }

  /**
   * 
   * 更新最新分数和最高分数
   */
  updateScore(score) {
    // 清除去原分数
    ctx.clearRect(0.28 * w, 50 + 0.08 * w, 0.32 * w, 0.08 * w);
    ctx.fillStyle = '#BAAB9E'
    ctx.fillRect(0.28 * w, 50 + 0.08 * w, 0.32 * w, 0.08 * w)
    ctx.clearRect(0.64 * w, 50 + 0.08 * w, 0.32 * w, 0.08 * w);
    ctx.fillStyle = '#F7921E'
    ctx.fillRect(0.64 * w, 50 + 0.08 * w, 0.32 * w, 0.08 * w)

    if (topScore < score) {
      topScore = score;
    }
    // 显示新分数
    ctx.fillStyle = 'white'
    ctx.font = "20px 微软雅黑"
    ctx.textAlign = "center"
    ctx.textBaseline = "top"
    ctx.fillText(score, 0.8 * w, 50 + 0.08 * w);
    ctx.fillText(topScore, 0.44 * w, 50 + 0.08 * w);

    return true;
  }

  /**
   * 游戏结束激活处理事件
   */
  touchEventHandler(e) {
    var touch = e.touches[0]
    var cx = touch.clientX
    var cy = touch.clientY

    var area = this.bg.btnArea

    if (cx >= area.startX &&
      cx <= area.endX &&
      cy >= area.startY &&
      cy <= area.endY) {
      this.restart()
    }
  }
}